package com.sunday.common.core.utils;

import com.sunday.common.core.enums.OperatorTypeEnum;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;

/**
 * 运营商识别（初步判定，不包换协转号码）
 *
 * @author zsy
 * @since 2022/10/11
 */
public class PhoneUtils {

    public static final int PHONE_SIZE = 11;

    public static String cmReg = "^1(3[5-9]|4[78]|5[01289]|8[23478]|7[28]|9[578]|65)[0-9]{8}|(170[356][0-9]{7})|(157[0-79][0-9]{7})|(1440[0-9]{7})|(134[0-8][0-9]{7})"; //170[356]
    public static String cuReg = "^1(6[67]|3[012]|5[56]|8[56]|4[56]|7[156]|96)[0-9]{8}|(170[7-9][0-9]{7})|(1704[0-9]{7})"; //170[4789],171
    public static String ctReg = "^1(33|53|62|7[37]|8[019]|49|9[0139])[0-9]{8}|(170[0-2][0-9]{7})|(1349[0-9]{7})|(1410[0-9]{7})|(1740[0-5][0-9]{6})";//170[012]

    /**
     * 验证号码有效性 并 清洗出正确号码
     *
     * @param phone
     * @return {@link Result}
     */
    public static Result validate(String phone) {
        Result result = new Result(phone);
        //号码为空 || 清洗号码并检测号码长度
        if (StringUtils.isBlank(phone) || (phone = rinse(phone)).length() != PHONE_SIZE) {
            return result;
        }
        // 清洗号码后更新号码
        result.setMobile(phone);
        if (phone.matches(cuReg)) {
            result.setOperator(OperatorTypeEnum.CHINA_UNICOM);
        } else if (phone.matches(cmReg)) {
            result.setOperator(OperatorTypeEnum.CHINA_MOBILE);
        } else if (phone.matches(ctReg)) {
            result.setOperator(OperatorTypeEnum.CHINA_TELECOM);
        }
        return result;
    }


    /**
     * 清洗号码无用标注
     * 例如 : 前后空格, +, 86
     *
     * @param phone
     * @return {@link String}
     */
    static String rinse(String phone) {
        phone = phone.trim();
        if (phone.startsWith("+")) {
            phone = phone.substring(1);
        }
        if (phone.startsWith("86")) {
            phone = phone.substring(2);
        }
        return phone;
    }

    /**
     * 号码验证结果
     *
     * @author zsy
     * @since 2022/10/11
     */
    @Data
    public static class Result {

        private String mobile;
        private OperatorTypeEnum operator;

        Result(String mobile) {
            this.mobile = mobile;
        }

        /**
         * 解析是否成功
         */
        public boolean isSuccess() {
            return operator != null;
        }

    }

}
